package com.sys.basics.utils.codeGenerator;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.sys.basics.utils.YmlUtils;

import java.util.*;

public class MybatisPlusGenerator {
    /**
     * @author: ares
     * @date: 2021/9/26 21:04
     * @description: 读取控制台内容
     */
    public static String scanner(String tip, String defaultStr) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + " ( 默认使用 " + defaultStr + " )【按Enter键使用默认值】：" );
        System.out.println(help.toString());
        if (scanner.hasNextLine()) {
            String ipt = scanner.nextLine();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            } else {
                return defaultStr;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "！" );
    }

    public static void main(String[] args) {
        // 数据库
        String DB_URL = YmlUtils.get("spring.datasource.url");
        // 数据库用户名
        String DB_USERNAME = YmlUtils.get("spring.datasource.username");
        // 数据库密码
        String DB_PASSWORD = YmlUtils.get("spring.datasource.password");
        // 数据库驱动
        String DB_DRIVER_NAME = YmlUtils.get("spring.datasource.driver-class-name");

        // 模块名
        String MODULE_NAME = scanner("模块名", "basics" );
        // 表名
        String TABLE_NAMES = scanner("表名，多个英文逗号分割", "test" );
        // 作者
        String AUTHOR = scanner("作者名称", "ares" );

        // 输出路径
        String OUTPUT_PATH_PREFIX = System.getProperty("user.dir" ) + "/src/main/";

        // 公共包名
        String PARENT_PACKAGE = "com.sys";
        // mapper包名
        String MAPPER_NAME = "dao";

        // 模板引擎路径
        String TEMPLATE_PATH = "/templates/mybatisplus/";

        // 公共父类包路径
        String SUPER_CONTROLLER_NAME = "AbstractController";
        String SUPER_CONTROLLER_PACKAGE_NAME = "controller";
        String SUPER_CONTROLLER_PACKAGE = PARENT_PACKAGE + "." + MODULE_NAME + "." + SUPER_CONTROLLER_PACKAGE_NAME;
        String SUPER_CONTROLLER_CLASS = SUPER_CONTROLLER_PACKAGE + "." + SUPER_CONTROLLER_NAME;
        String SUPER_CONTROLLER_CLASS_PATH = "/" + SUPER_CONTROLLER_PACKAGE.replace(".", "/") + "/";
        // 你自己的父类实体,没有就不用设置
        String SUPER_ENTITY_CLASS = "";
        // 写于父类中的公共字段
        String SUPER_ENTITY_COLUMNS = "id";

        // 代码生成器
        AutoGenerator autoGenerator = new AutoGenerator();

        // 全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(OUTPUT_PATH_PREFIX + "java" );
        globalConfig.setAuthor(AUTHOR);
        globalConfig.setServiceName("%sService" );
        globalConfig.setMapperName("%sDao" );
        globalConfig.setOpen(false);
        globalConfig.setFileOverride(false);
        globalConfig.setSwagger2(true);
        globalConfig.setBaseResultMap(true);
        globalConfig.setBaseColumnList(true);
        autoGenerator.setGlobalConfig(globalConfig);


        // 数据源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setUrl(DB_URL);
        dataSourceConfig.setDriverName(DB_DRIVER_NAME);
        dataSourceConfig.setUsername(DB_USERNAME);
        dataSourceConfig.setPassword(DB_PASSWORD);
        autoGenerator.setDataSource(dataSourceConfig);

        // 包配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setModuleName(MODULE_NAME);
        packageConfig.setParent(PARENT_PACKAGE);
        packageConfig.setMapper(MAPPER_NAME);
        autoGenerator.setPackageInfo(packageConfig);

        // 自定义配置
        InjectionConfig injectionConfig = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> map = new HashMap<>();
                map.put("superControllerPackage", SUPER_CONTROLLER_PACKAGE);
                map.put("dateTime", DateUtil.now());
                this.setMap(map);
            }
        };

        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义输出XML文件位置
        focList.add(new FileOutConfig(TEMPLATE_PATH + "mapper.xml.vm" ) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                return OUTPUT_PATH_PREFIX + "resources/mapper/" + packageConfig.getModuleName()
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        // 自定义输出父controller文件位置
        focList.add(new FileOutConfig(TEMPLATE_PATH + "abstractController.java.vm" ) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return OUTPUT_PATH_PREFIX + "java" + SUPER_CONTROLLER_CLASS_PATH + SUPER_CONTROLLER_NAME + StringPool.DOT_JAVA;
            }
        });
        injectionConfig.setFileOutConfigList(focList);
        autoGenerator.setCfg(injectionConfig);

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();
        // 配置自定义输出模板
        //指定自定义模板路径，注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
        templateConfig.setController(TEMPLATE_PATH + "controller.java");
//        templateConfig.setController(null);
        templateConfig.setEntity(TEMPLATE_PATH + "entity.java");
//        templateConfig.setEntity(null);
        templateConfig.setMapper(TEMPLATE_PATH + "mapper.java");
//        templateConfig.setMapper(null);
        templateConfig.setService(TEMPLATE_PATH + "service.java");
//        templateConfig.setService(null);
        templateConfig.setServiceImpl(TEMPLATE_PATH + "serviceImpl.java");
//        templateConfig.setServiceImpl(null);
        templateConfig.setXml(null);
        autoGenerator.setTemplate(templateConfig);

        // 策略配置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setInclude(TABLE_NAMES.split("," ));
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setEntityLombokModel(true);
        strategyConfig.setRestControllerStyle(true);
        strategyConfig.setControllerMappingHyphenStyle(false);
        strategyConfig.setEntityTableFieldAnnotationEnable(true);
        strategyConfig.setTablePrefix(packageConfig.getModuleName() + "_" );

        strategyConfig.setSuperControllerClass(SUPER_CONTROLLER_CLASS);
        /*strategyConfig.setSuperEntityClass(SUPER_ENTITY_CLASS);
        strategyConfig.setSuperEntityColumns(SUPER_ENTITY_COLUMNS);  */

        // 自动填充创建时间和修改时间
        TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
        TableFill gmtModified = new TableFill("gmt_modified", FieldFill.INSERT_UPDATE);
        TableFill creatorId = new TableFill("creator_id", FieldFill.INSERT);
        TableFill modifierId = new TableFill("modifier_id", FieldFill.INSERT_UPDATE);
        ArrayList<TableFill> tableFills = new ArrayList<>();
        tableFills.add(gmtCreate);
        tableFills.add(gmtModified);
        tableFills.add(creatorId);
        tableFills.add(modifierId);
        strategyConfig.setTableFillList(tableFills);

        // 乐观锁
        strategyConfig.setVersionFieldName("version" );

        // 逻辑删除
        strategyConfig.setLogicDeleteFieldName("deleded" );

        autoGenerator.setStrategy(strategyConfig);
        autoGenerator.execute();
    }

}
